package com.sina.interfaces.manage.service.sys;


import com.sina.interfaces.core.exception.client.DataException;
import com.sina.interfaces.core.exception.server.ResourceExistsException;
import com.sina.interfaces.core.exception.server.UpdateException;
import com.sina.interfaces.core.util.Assert;
import com.sina.interfaces.core.util.CollectionUtils;
import com.sina.interfaces.core.util.ResultCode;
import com.sina.interfaces.core.util.StringUtils;
import com.sina.interfaces.domain.sys.Permission;
import com.sina.interfaces.domain.sys.Role;
import com.sina.interfaces.manage.dao.sys.PermissionManageDao;
import com.sina.interfaces.manage.dao.sys.RoleManageDao;
import com.sina.interfaces.service.InterFacesDataSourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static com.sina.interfaces.service.ServiceConstant.INTERFACE_TX;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * 段浩杰   2017-11-01-13:07
 */
@Service("roleManageService")
public class RoleManageServiceImpl extends InterFacesDataSourceService implements RoleManageService {

    @Autowired
    @Qualifier("roleManageDao")
    private RoleManageDao roleManageDao;

    @Autowired
    @Qualifier("permissionManageDao")
    private PermissionManageDao permissionManageDao;

    @Override
    @Transactional(value = INTERFACE_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public Role getRoleByName(String name) {
        return roleManageDao.getRoleByName(name);
    }

    @Override
    @Transactional(value = INTERFACE_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public Role getRoleById(Integer id) {
        return roleManageDao.get(Role.class, id);
    }

    @Override
    @Transactional(value = INTERFACE_TX, isolation = Isolation.REPEATABLE_READ)
    public Role saveRole(Role role) throws UpdateException, DataException {
        boolean exists;
        exists = roleManageDao.isExistsByUnique(Role.class, "name", role.getName());
        Assert.assertFalse(exists, ResourceExistsException.class, ResultCode.dataExists
                , "Role[%s] exists", role.getName());

        try {
            roleManageDao.save(role);
            roleManageDao.flush();

            return role;
        } catch (DataAccessException e) {
            LOG.error(" {} save Role error.", Role.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    @Override
    @Transactional(value = INTERFACE_TX, isolation = Isolation.REPEATABLE_READ)
    public Role updateRole(Role role) throws UpdateException, DataException {

        Role r = roleManageDao.get(Role.class, role.getId());
        Assert.assertNotNull(r, "Role[id=%s] not exists", role.getId());

        try {
            updateRoleFiled(role, r);
            roleManageDao.flush();

            return r;
        } catch (DataAccessException e) {
            LOG.error(" {} update Role error.", Role.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }

    }

    /*转化更新的属性*/
    private Role updateRoleFiled(Role oldRole, Role newRole) {

        if (!StringUtils.isEmpty(oldRole.getName())) {
            newRole.setName(oldRole.getName());
        }
        if (!CollectionUtils.isEmpty(oldRole.getAdmins())) {
            newRole.setAdmins(oldRole.getAdmins());
        }
        if (!CollectionUtils.isEmpty(oldRole.getPermissions())) {
            Set<Permission> permissions = getUpdateRoleAndPermission(oldRole.getPermissions());
            newRole.setPermissions(permissions);
        }

        return newRole;
    }

    /*转化关联表中所要更新的属性*/
    private Set<Permission> getUpdateRoleAndPermission(Set<Permission> perms) {
        Set<Permission> permissions = new HashSet<>();
        Iterator<Permission> iterator = perms.iterator();
        while (iterator.hasNext()) {
            Permission permission = iterator.next();
            if (permission != null && permission.getId() != null) {
                permission = permissionManageDao.get(Permission.class, permission.getId());
                permissions.add(permission);
            }
        }
        return permissions;
    }

    @Override
    @Transactional(value = INTERFACE_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public List<Map<String, Object>> getRoleList(Role role, Long[] count) {

        if (count != null && count.length > 0) {
            count[0] = roleManageDao.getRoleCount(role);
        }

        return roleManageDao.getRoleList(role);
    }

    @Override
    @Transactional(value = INTERFACE_TX, isolation = Isolation.REPEATABLE_READ)
    public int deleteRole(Integer id) throws UpdateException, DataException {

        Role r = roleManageDao.get(Role.class, id);
        Assert.assertNotNull(r, "Role[id=%s] not exists", r.getId());

        try {
            return roleManageDao.deleteRole(id);
        } catch (DataAccessException e) {
            LOG.error(" {} delete Role error.", Role.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }
}
